﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LPLib
{
    /// <summary>
    /// Provides methods to produce the complements of polynucleotide sequences.
    /// </summary>
    /// <typeparam name="T">The type of the nucleotide representation.</typeparam>
    public class Complementer<T>
    {
        private MonomerEncoding<T> nucleotideEncoding;

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="_nucleotide">An instance of the relevant NucleotideEncoding class.</param>
        public Complementer(MonomerEncoding<T> _nucleotide)
        {
            nucleotideEncoding = _nucleotide;
        }

        /// <summary>
        /// Produces the complement of a Polynucleotide.
        /// </summary>
        /// <param name="p">The polynucleotide to be complemented.</param>
        /// <returns>The polynucleotide whose sequence is the complement of the input polynucleotide. The name has ".C" appended.</returns>
        public Polymer<T> Complement(Polymer<T> p)
        {
            Polymer<T> c;
            string newName = p.Name + ".C";
            if (p.Qual != null)
            {
                 c = new Polymer<T>(nucleotideEncoding, newName, Complement(p.Seq), p.Qual.Reverse().ToArray());
            }
            else
            {
                 c = new Polymer<T>(nucleotideEncoding, newName, Complement(p.Seq));
            }
            return c;
        }

        /// <summary>
        /// Produces the complement of a nucleotide array.
        /// </summary>
        /// <param name="seq">An array of nucleotides in the relevant encoding.</param>
        /// <returns>The complement of the input array.</returns>
        public T[] Complement(T[] seq)
        {
            T[] newSeq = new T[seq.Length];
            for (int i = 0; i < seq.Length; i++)
            {
                newSeq[i] = nucleotideEncoding.Complement(seq[seq.Length - 1 - i]);
            }
            return newSeq;
        }

        ///// <summary>
        ///// Complements all of the members of Polynucleotide collection.
        ///// </summary>
        ///// <param name="pc">A polynucleotide collection of the relevant type.</param>
        ///// <returns>A polynucleotide collection whose members are all complements of those of the input array.
        ///// The name of the return collection is that of the input collection with ".C" appended.</returns>
        //public PolynucleotideCollection<T> Complement(PolynucleotideCollection<T> pc)
        //{
        //    PolynucleotideCollection<T> pcc = new PolynucleotideCollection<T>();
        //    pcc.Name = pc.Name + ".C";
        //    foreach (Polynucleotide<T> p in pc)
        //    {
        //        pcc.AddMember(Complement(p));
        //    }
        //    return pcc;
        //}
    }

}
